package cn.com.easy.pay.weixinpay.controller;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.com.easy.exception.BusinessException;
import cn.com.easy.pay.weixinpay.config.WeixinPayConfig;
import cn.com.easy.pay.weixinpay.param.WeixinPayNotifyParam;
import cn.com.easy.pay.weixinpay.utils.Signature;
import cn.com.easy.utils.XmlUtils;

/**
 * 微信支付异步回调 基础控制器
 * 
 * @author nibili 2017年5月8日
 * 
 */
public abstract class WeixinPayNotifyBaseController {

	private Logger logger = LoggerFactory.getLogger(WeixinPayNotifyBaseController.class);

	/**
	 * 获取微信支付 config
	 * 
	 * @param reques
	 * @return
	 * @author nibili 2017年5月8日
	 */
	public abstract WeixinPayConfig getWeixinPayConfig(HttpServletRequest reques) throws BusinessException;;

	/**
	 * 支付成功时回调
	 * 
	 * @param weixinPayNotifyParam
	 * @throws BusinessException
	 * @author nibili 2017年5月8日
	 */
	public abstract void notityTradeSuccessCallback(WeixinPayNotifyParam weixinPayNotifyParam) throws BusinessException;

	/**
	 * 微信回调
	 * 
	 * @param request
	 * @param response
	 * @author nibili 2017年5月8日
	 */
	@ResponseBody
	@RequestMapping("/notify")
	public String notify(HttpServletRequest request, HttpServletResponse response) {
		// 成功和错误的返回值
		String successResXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
		String failResXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
		try {
			// 读取参数
			InputStream inputStream;
			StringBuffer sb = new StringBuffer();
			inputStream = request.getInputStream();
			String s;
			BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
			while ((s = in.readLine()) != null) {
				sb.append(s);
			}
			in.close();
			inputStream.close();

			// 判断签名是否正确
			WeixinPayConfig weixinPayConfig = getWeixinPayConfig(request);
			// 验证签名是否正确
			if (Signature.checkIsSignValidFromResponseString(sb.toString(), weixinPayConfig.getSign_type(), weixinPayConfig.getAppkey()) == true) {
				// logger.info("微信支付回调数据："+sb.toString());
				// 解析xml 成 java对象
				WeixinPayNotifyParam weixinPayNotifyParam = XmlUtils.xmlStrToObject(WeixinPayNotifyParam.class, sb.toString());
				// ------------------------------
				// 处理业务开始
				// ------------------------------
				if (StringUtils.equals("SUCCESS", weixinPayNotifyParam.getReturn_code()) == true && StringUtils.equals("SUCCESS", weixinPayNotifyParam.getResult_code())) {
					// 这里是支付成功
					// ////////执行自己的业务逻辑////////////////
					notityTradeSuccessCallback(weixinPayNotifyParam);
					// 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
					return successResXml;
				} else {
					throw new BusinessException("微信回调支付不正确异常");
				}
			} else {
				throw new BusinessException("通知签名验证失败");
			}
		} catch (BusinessException ex) {
			logger.error("微信回调发生异常(自定义异常):" + ex.getMessage(), ex);
			// 错误
		} catch (Exception ex) {
			logger.error("微信回调异常:" + ex.getMessage(), ex);
			// 错误
		}
		return failResXml;
	}
}
